﻿//========================================
// All rights reserved (C) 2017-2100
// CLR 版本：	4.0.30319.42000
// 命名空间:	Network.UpdateData
// 文 件 名：	Packet
// 作    者：	WooG
// 联系方式：	wooglle@163.com
// 创建时间：	2017/9/27 14:46:31
//========================================
using System;
using System.Linq;
using System.Net;
using System.Text;

namespace Network.UpdateData
{
    public struct Packet : IEquatable<Packet>
    {
        //ping -f -l 1472 192.168.2.1 数据包包头长28字节
        public const int BytesCount = 1024;
        public const int PacketHeaderCount = 40;
        public int Code { set; get; }
        public Guid GuidSend { set; get; }
        public Int32 IpSend { set; get; }
        public Guid GuidTarget { set; get; }
        public int MsgLenght { set; get; }
        public string Message { set; get; }

        public Packet(byte[] bytes)
        {
            Code = (int)BitConverter.ToInt16(bytes.Take(2).ToArray(), 0);
            GuidSend = new Guid(bytes.Skip(2).Take(16).ToArray());
            IpSend = BitConverter.ToInt32(bytes.Skip(18).Take(4).ToArray(), 0);
            GuidTarget = new Guid(bytes.Skip(22).Take(16).ToArray());
            MsgLenght = (int)BitConverter.ToInt16(bytes.Skip(38).Take(2).ToArray(), 0);
            Message = Encoding.BigEndianUnicode.GetString(bytes.Skip(PacketHeaderCount).Take(MsgLenght).ToArray());
            //this.Message = "0";
            //for (int i = 1023; i > 38; i--)
            //{
            //    if(bytes[i] != 0)
            //    {
            //        this.Message = Encoding.UTF8.GetString(bytes.Skip(38).Take(i - 37).ToArray());
            //        break;
            //    }
            //}
        }

        public Packet(int code, Guid guidSend, Guid guidTarget, string msg)
        {
            Code = code;
            GuidSend = guidSend;
            //IpSend = BitConverter.ToInt32(Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault<IPAddress>(a => a.AddressFamily.ToString().Equals("InterNetwork")).GetAddressBytes(), 0);
            IpSend = BitConverter.ToInt32(Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault<IPAddress>(a => a.ToString().StartsWith("192.168.")).GetAddressBytes(), 0);

            //this.IpSend = BitConverter.ToInt32(IPAddress.Parse("127.0.0.1").GetAddressBytes(), 0);
            GuidTarget = guidTarget;
            MsgLenght = Encoding.BigEndianUnicode.GetByteCount(msg);
            Message = msg;
        }

        public Packet(int code, Guid guidSend, string msg)
        {
            Code = code;
            GuidSend = guidSend;
            //IpSend = BitConverter.ToInt32(Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault<IPAddress>(a => a.AddressFamily.ToString().Equals("InterNetwork")).GetAddressBytes(), 0);
            IpSend = BitConverter.ToInt32(Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault<IPAddress>(a => a.ToString().StartsWith("192.168.")).GetAddressBytes(), 0);
            //this.IpSend = BitConverter.ToInt32(IPAddress.Parse("127.0.0.1").GetAddressBytes(), 0);
            GuidTarget = Guid.Empty;
            MsgLenght = Encoding.BigEndianUnicode.GetByteCount(msg);
            Message = msg;
        }

        public byte[] ToBytes()
        {
            byte[] b = new byte[BytesCount];
            try
            {
                Buffer.BlockCopy(BitConverter.GetBytes(Code), 0, b, 0, 2);
                Buffer.BlockCopy(GuidSend.ToByteArray(), 0, b, 2, 16);
                Buffer.BlockCopy(BitConverter.GetBytes(IpSend), 0, b, 18, 4);
                Buffer.BlockCopy(GuidTarget.ToByteArray(), 0, b, 22, 16);
                Buffer.BlockCopy(BitConverter.GetBytes(MsgLenght), 0, b, 38, 2);
                byte[] t = Encoding.BigEndianUnicode.GetBytes(Message);
                Buffer.BlockCopy(t, 0, b, PacketHeaderCount, t.Length);
            }
            catch { }
            return b;
        }

        //public static implicit operator string(Packet packet)
        //{
        //    return packet.Equals(null) ? null : packet.ToString();
        //}

        public static implicit operator Packet(byte[] value)
        {
            return new Packet(value);
        }

        public override string ToString()
        {
            string b = "";
            b += Code.ToString() + ", ";
            b += GuidSend.ToString() + ", ";
            //b += this.ipSend.ToString() + ", ";
            b += new IPAddress(BitConverter.GetBytes(IpSend)) + ", ";
            b += GuidTarget.ToString() + ", ";
            b += MsgLenght.ToString() + ", ";
            b += Message;
            return b;
        }

        public bool Equals(Packet other)
        {
            if(Code == other.Code && GuidSend.Equals(other.GuidSend) && GuidTarget.Equals(other.GuidTarget))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}
